import type { LngLat } from 'mapbox-gl';
import { ShapeTool } from './shape';

export class PositionTool extends ShapeTool {
  private pointMarkersSource = 'dzmap-draw-point-markers-source';
  private pointMarkersLayer = 'dzmap-draw-point-markers-layer';

  async startPointPickingAsync(): Promise<[LngLat?, Error?]> {
    if (!this.draw?.map) return [undefined, new Error('Map not initialized')];
    // 设置地图光标样式
    this.draw.map.getCanvas().style.cursor = 'crosshair';
    // 创建一个Promise，用于异步获取坐标
    return new Promise<[LngLat?, Error?]>((resolve, reject) => {
      if (!this.draw?.map) return reject('map is not ready');

      const mapClickHandler = (e: mapboxgl.MapMouseEvent) => {
        // 恢复原始光标
        if (!this.draw?.map) return reject('map is not ready');
        this.draw.map.getCanvas().style.cursor = '';
        // 获取坐标并格式化
        const coords = e.lngLat;
        // 绘制marker
        this.addPointMarker(coords);
        resolve([coords, undefined]);
      };

      // 添加临时点击事件
      this.draw?.map?.once('click', mapClickHandler);

      const escHandler = (e: KeyboardEvent) => {
        if (e.key === 'Escape') {
          // 恢复原始光标
          if (!this.draw?.map) return reject('map is not ready');
          this.draw.map.getCanvas().style.cursor = '';
          resolve([undefined, new Error('picking canceled')]);

          this.draw?.map?.off('click', mapClickHandler);
          window.removeEventListener('keydown', escHandler);
        }
      };

      window.addEventListener('keydown', escHandler);
    });
  }

  startPointPicking() {
    if (!this.draw?.map) return;

    // 设置地图光标样式
    this.draw.map.getCanvas().style.cursor = 'crosshair';

    const mapClickHandler = (e: mapboxgl.MapMouseEvent) => {
      // 恢复原始光标
      if (!this.draw?.map) return;
      this.draw.map.getCanvas().style.cursor = '';

      // 获取坐标并格式化
      const coords = e.lngLat;

      // 绘制marker
      this.addPointMarker(coords);

      const coordText = `经度: ${coords.lng.toFixed(6)}, 纬度: ${coords.lat.toFixed(6)}`;

      // 复制到剪贴板
      navigator.clipboard
        .writeText(coordText)
        .then(() => {
          alert(`坐标已复制: ${coordText}`);
        })
        .catch(() => {
          alert(`坐标获取成功: ${coordText}`);
        });
    };

    // 添加临时点击事件
    this.draw?.map?.once('click', mapClickHandler);

    const escHandler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        // 恢复原始光标
        if (!this.draw?.map) return;
        this.draw.map.getCanvas().style.cursor = '';
        this.draw?.map?.off('click', mapClickHandler);
        window.removeEventListener('keydown', escHandler);
      }
    };

    window.addEventListener('keydown', escHandler);
  }

  private addPointMarker(coords: LngLat) {
    if (!this.draw?.map) return;

    // 检查并创建数据源和图层（如果不存在）
    if (!this.draw?.map.getSource(this.pointMarkersSource)) {
      this.draw?.map.addSource(this.pointMarkersSource, {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: [],
        },
      });

      this.draw?.map.addLayer({
        id: this.pointMarkersLayer,
        type: 'symbol',
        source: this.pointMarkersSource,
        layout: {
          'icon-image': 'dot-9',
          'icon-size': 2,
          'text-field': [
            'format',
            ['get', 'lng'],
            { 'font-scale': 0.8 },
            ',',
            ['get', 'lat'],
            { 'font-scale': 0.8 },
          ],
          'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Regular'],
          'text-size': 14,
          'text-offset': [0, 0.6],
          'text-anchor': 'top',
        },
      });
    }

    // 获取当前所有marker
    const source = this.draw?.map.getSource(
      this.pointMarkersSource,
    ) as mapboxgl.GeoJSONSource;
    const currentData = source._data as GeoJSON.FeatureCollection;

    // 添加新marker
    const newFeature: GeoJSON.Feature = {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [coords.lng, coords.lat],
      },
      properties: {
        lng: coords.lng.toFixed(6),
        lat: coords.lat.toFixed(6),
      },
    };

    // 更新数据源
    source.setData({
      ...currentData,
      features: [...currentData.features, newFeature],
    });
  }

  clearLayers = () => {
    if (this.draw?.map?.getLayer(this.pointMarkersLayer)) {
      this.draw?.map?.removeLayer(this.pointMarkersLayer);
    }
    if (this.draw?.map?.getLayer(this.pointMarkersSource)) {
      this.draw?.map?.removeLayer(this.pointMarkersSource);
    }
  };
}
